package com.lc.parser;

import com.lc.adapter.HttpAdapter;
import com.lc.config.Configuration;
import com.lc.mapper.Context;
import com.lc.mapper.Host;
import com.lc.mapper.HttpServlet;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.InputStream;
import java.util.*;

/**
 * @author liuc
 * @date 2021/5/9
 * @description
 **/
public class ServerXmlParser {
    private Configuration configuration;
    private InputStream is;

    public ServerXmlParser(Configuration configuration, InputStream is) {
        this.configuration = configuration;
        this.is = is;
    }

    public void parse(){
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(this.is);
            Element rootElement = document.getRootElement();
            //拿到service标签
            List<Element> selectNodes = rootElement.selectNodes("//service");
            for (int i = 0; i < selectNodes.size(); i++) {
                Element element =  selectNodes.get(i);
                //<connector port="8090"/>
                Element connectorElm = (Element) element.selectSingleNode("connector");
                String port = connectorElm.attributeValue("port");
                this.configuration.setPort(Integer.parseInt(port));
                //<engine>
                Element engineElm = (Element) element.selectSingleNode("engine");
                //<host name="localhost" appBase="/webapps" />
                Element hostElm = (Element) engineElm.selectSingleNode("host");
                //配置host
                String hostName = hostElm.attributeValue("name");
                String appBase = hostElm.attributeValue("appBase");
                loadHostConfig(hostName,appBase);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void loadHostConfig(String hostName, String appBase){
        //拿到一个adapter
        HttpAdapter adapter = this.configuration.getAdapter(hostName);
        if(adapter.getHost() == null){
            adapter.setHost(new Host(hostName));
        }
        Host host = adapter.getHost();
        File file = new File(appBase);
        if(file.exists() && file.isDirectory()){
            File[] files = file.listFiles();
            for (File f : files) {
                if(f.isDirectory()){
                    File[] childs = f.listFiles();
                    Context context = null;
                    if(childs != null && childs.length > 0){
                        //创建context
                        context = new Context("/"+f.getName());
                        context.setDir(f.getAbsolutePath());
                        host.addContext(context);
                    }
                    String packageName = appBase+"/"+f.getName();

                    File webXml = null;
                    for (File c : childs) {
                        //查看是否有web.xml文件
                        if("web.xml".equals(c.getName())){
                            webXml = c;
                        }
                    }
                    if(webXml != null){
                        Set<Class> set = new HashSet<>();
                        for (File c : childs) {
                            //查看是否有web.xml文件
                            if("web.xml".equals(c.getName())){
                                continue;
                            }
                            loadAppBaseServlet(c,set,packageName);
                        }
                        //找到了HttpServlet的实现类
                        if(!set.isEmpty()){
                            WebXmlParser webXmlParser = new WebXmlParser(webXml,context,set);
                            webXmlParser.parse();
                        }
                    }
                }
            }
        }
    }

    public void loadAppBaseServlet(File file, Set<Class> set, String packageName){
        if(file.isDirectory()){
            File[] files = file.listFiles();
            if(files != null && files.length > 0){
                for (File f : files) {
                    loadAppBaseServlet(f,set,packageName);
                }
            }

        }
        if(file.getName().endsWith(".class")){
            //判断是否是servlet
            Class<?> aClass = null;
            try {
                String class1Name = file.getAbsolutePath().replace(packageName,"");
                String class2Name = class1Name.replaceAll("/", ".");
                class2Name = class2Name.substring(class2Name.indexOf(".")+1);
                String className = class2Name.substring(0, class2Name.lastIndexOf('.'));
                aClass = this.getClass().getClassLoader().loadClass(className);
                if(HttpServlet.class.isAssignableFrom(aClass)){
                    set.add(aClass);
                }
            } catch (ClassNotFoundException e) {
                System.out.println(e.getMessage());
            }
        }
    }
}
